// Author:
// Title:

#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform float u_time;
/**
 * hash - 生成二维向量的伪随机值
 * @param p: 输入的二维向量
 * @return: 返回一个范围在 [-1, 1] 的二维向量，用于噪声函数中的梯度方向
 */
vec2 hash(vec2 p) {
    p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
    return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
}

/**
 * noise - 实现二维 Simplex Noise（简化版 Perlin 噪声）
 * @param p: 输入的二维坐标点
 * @return: 返回该点的噪声值，范围约为 [-1, 1]
 */
float noise(in vec2 p) {
    const float K1 = 0.366025404; // (sqrt(3)-1)/2;
    const float K2 = 0.211324865; // (3-sqrt(3))/6;

    // 将输入点转换到单纯形网格空间
    vec2 i = floor(p + (p.x + p.y) * K1);
    vec2 a = p - i + (i.x + i.y) * K2;

    // 确定三角形的其他两个顶点
    vec2 o = (a.x > a.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
    vec2 b = a - o + K2;
    vec2 c = a - 1.0 + 2.0 * K2;

    // 计算每个顶点对当前点的影响权重（衰减因子）
    vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);

    // 使用 hash 函数获取梯度并计算噪声贡献
    vec3 n = h * h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));

    // 加权求和得到最终噪声值
    return dot(n, vec3(70.0));
}

/**
 * fbm - 分形布朗运动（Fractal Brownian Motion）噪声生成函数
 * @param uv: 输入的纹理坐标
 * @return: 返回多层噪声叠加后的结果，用于生成更自然的纹理效果
 */
float fbm(vec2 uv) {
    float f;
    mat2 m = mat2(1.6, 1.2, -1.2, 1.6); // 变换矩阵，用于旋转和缩放每层噪声

    // 多层噪声叠加，每层频率翻倍、振幅减半
    f = 0.5000 * noise(uv);
    uv = m * uv;
    f += 0.2500 * noise(uv);
    uv = m * uv;
    f += 0.1250 * noise(uv);
    uv = m * uv;
    f += 0.0625 * noise(uv);
    uv = m * uv;

    // 调整输出范围至 [0, 1]
    f = 0.5 + 0.5 * f;
    return f;
}

/**
 * main - 片段着色器主函数
 * 根据屏幕坐标生成动态噪声图案，并映射为颜色输出
 */
void main() {
    // 归一化屏幕坐标
    vec2 uv = gl_FragCoord.xy / u_resolution.xy;

    vec2 q = uv;

    // 对 x 和 y 方向进行拉伸以适应视觉效果
    q.x *= 5.;
    q.y *= 2.;

    // 根据 x 坐标确定区域强度，用于控制动画速度和细节密度
    float strength = floor(q.x + 1.);
    float T3 = strength * u_time;

    // 将 x 坐标归一化到 [0,1) 区间，并居中处理
    q.x = fract(q.x) - 0.5;
    q.y -= 0.25;

    // 使用 fbm 生成噪声值，结合时间与强度变化形成动态效果
    float n = fbm(strength * q - vec2(0, T3));

    // 生成基于距离和噪声的平滑过渡值
    float c1 = smoothstep(0.1, 0.4, length(vec2(q.x * 6., q.y)) * n) + 0.18;

    // 构造颜色值，使用不同权重混合 RGB 分量
    vec3 col = vec3(16.948 * c1, 1.980 * c1, c1 * 0.732);

    // 计算透明度，通过幂函数增强边缘对比
    float a = pow(c1, 6.);

    // 混合背景色（黑色）与前景色，输出最终颜色
    gl_FragColor = vec4(mix(col, vec3(0.), a), 1.0);
}